// Header Protection
#ifndef _EVENT_H_
#define _EVENT_H_

// Include Files for .cpp? used in Raise, AddRegistration, RemoveRegistration
#include "Event\Registration.h"

/////////////////////////////////////////////////////////////////////////////////////
// Classes contain events which they can raise whenever necessary.
template< class eventarg_t >
class CEvent
{
public:     // methods

	inline CEvent() : m_RegMutex(), m_lstRegs() { }
	inline ~CEvent()
	{
#ifdef _DEBUG
		// make sure all listeners have been unregistered
		uint_t uRegCount = m_lstRegs.GetSize();
		for( uint_t i = 0; i < uRegCount; ++i )
		{
			assert( !m_lstRegs[i] );
		}
#endif // _DEBUG
	}

	// Raise the event. The argument will be passed on to each registered handler.
	// _pArg : eventarg_t * - the argument to send to each handler
	void Raise( eventarg_t *_pArg );

private:    // IListener friend methods
	friend class IListener;

	// Add a registration, associating a listener and event handler with the event.
	// listener_t : template - the type of the listener
	// _pListener : listener_t - the event listener
	// _pHandler : void (listener_t::*)(eventarg_t &) - the event handler
	template< class listener_t >
	void AddRegistration( 
		listener_t *_pListener, void (listener_t::*_pHandler)(eventarg_t &) );

	// Remove a registration with the given listener and event handler. If more than 
	//     one registration matches, the most recent is removed.
	// listener_t : template - the type of the listener
	// _pListener : listener_t - the event listener
	// _pHandler : void (listener_t::*)(eventarg_t &) - the event handler
	template< class listener_t >
	void RemoveRegistration( 
		listener_t *_pListener, void (listener_t::*_pHandler)(eventarg_t &) );

private:    // data
	mutex_t                  m_RegMutex;
	list_t<ABCRegistration*> m_lstRegs;

private:    // dummy definitions
	CEvent( CEvent const & );
	CEvent &operator =( CEvent const & );
};

// CEvent Template Implementation
#include "Event\Event.hpp"

// Header Protection
#endif // _EVENT_H_
